﻿using SuperSocket.SocketBase;
using SuperSocket.SocketBase.Protocol;
using System;
using System.IO;
using Message;
using System.Collections.Generic;

namespace LoginServer.Net
{
    public class PlayerSession : AppSession<PlayerSession, BinaryRequestInfo>
    {
        public int uid = -1;
        public string uname;

        private bool isSending = false;
        private Queue<byte[]> sendCache = new Queue<byte[]>();

        public long lastTickTime = long.MinValue;

        public bool isUse = false;

        public float x;
        public float y;
        public float z;
        public float angle;

        protected override void HandleException(Exception e)
        {
            base.HandleException(e);
            Console.WriteLine(uid + "HandleException  " + e.ToString());
            Close();
        }

        /// <summary>
        /// 连接开始
        /// </summary>
        protected override void OnSessionStarted()
        {
            base.OnSessionStarted();
            isUse = true;
            lastTickTime = Sys.GetTimeStamp();
            Console.WriteLine(uid + "OnSessionStarted  ");
        } 

        public void Receive(string key, byte[] body)
        {
            //Console.WriteLine("处理消息 " + key);
            int protoId = Convert.ToInt32(key);
            Type protoType = ProtoDic.GetProtoTypeByProtoId(protoId);
            object toc = ProtoBuf.Serializer.Deserialize(protoType, new MemoryStream(body));
            //注册
            if (protoId == 1001)
            {
                CToSRegister ctsr = toc as CToSRegister;
                Console.WriteLine(ctsr.uname + " " + ctsr.pwd);

                SToCRegisterRet stcr = new SToCRegisterRet();
                if (DataMgr.instance.Register(ctsr.uname, ctsr.pwd))
                {
                    Console.WriteLine("0");
                    stcr.code = 0;
                }
                else
                {
                    Console.WriteLine("-1");
                    stcr.code = -1;
                }
                SendObj(stcr);
            }
            //登录
            if (protoId == 1003)
            {
                CToSLogin ctsl = toc as CToSLogin;
                Console.WriteLine(ctsl.uname + " " + ctsl.pwd);
                SToCLoginRet stcl = new SToCLoginRet();
                uid = DataMgr.instance.CheckPassWord(ctsl.uname, ctsl.pwd);

                if (uid > -1)
                {
                    stcl.code = 0;
                    stcl.uid = uid;
                    if (!ServNet.instance.Users.ContainsKey(uid))
                    {
                        ServNet.instance.Users.Add(uid, this);
                    }
                    else
                    {
                        ServNet.instance.Users[uid].Close();
                        ServNet.instance.Users.Remove(uid);
                        ServNet.instance.Users.Add(uid, this);
                    }
                    uname = ctsl.uname;
                }
                else
                {
                    stcl.code = -1;
                }
                SendObj(stcl);
            }
            //心跳
            if (protoId == 1005)
            {
                SToCHeatBeat stshb = new SToCHeatBeat();
                TimeSpan ts = new TimeSpan(DateTime.Now.Ticks);
                stshb.time = (long)ts.TotalMilliseconds;
                SendObj(stshb);
                lastTickTime = Sys.GetTimeStamp();
            }
            //登出
            if (protoId == 1007)
            {
                CToSLogout stshb = toc as CToSLogout;
                Close();
                //SendObj(stshb); 
            }
            //消息
            if (protoId == 1009)
            {
                CToSChat ctsc = toc as CToSChat;
            }
            //添加好友
            if (protoId == 1011)
            {
                CToSAddFriend ctsc = toc as CToSAddFriend;
            }

            //同意或拒绝添加好友
            if (protoId == 1013)
            {
                CToSAddFriendRet ctsc = toc as CToSAddFriendRet;
            }

            //删除好友
            if (protoId == 1015)
            {
                CToSDelFriend ctsc = toc as CToSDelFriend;
            }

            //删除好友回馈
            if (protoId == 1017)
            {
                CToSDelFriendRet ctsc = toc as CToSDelFriendRet;
            }
            //获取在线玩家列表
            if (protoId == 1019)
            {
                CToSGetPlayerList ctsg = toc as CToSGetPlayerList;

                SToCGetPlayerList stcgl = new SToCGetPlayerList();

                foreach (KeyValuePair<int, PlayerSession> user in ServNet.instance.Users)
                {
                    Player p = new Player();
                    p.uid = user.Value.uid;
                    p.uname = user.Value.uname;
                    stcgl.players.Add(p);
                }
                SendObj(stcgl);
            }
            //玩家发过来的位置旋转数据
            if (protoId == 1021)
            {
                CToSMove ctsm = toc as CToSMove;
                x = ctsm.x;
                y = ctsm.y;
                z = ctsm.z;
                angle = ctsm.angle;
            }

        }

        public void SendObj(object proto)
        {
            if (!isUse)
            {
                Console.WriteLine(uid + "SendObj  "+ isUse);
                return;
            }
               
            if (!isSending)
            {
                byte[] data = NetCode.Encode(proto);
                sendCache.Enqueue(data); 
                Send();
            }
        }

        private void Send()
        {
            try
            {
                if (sendCache.Count == 0)
                {
                    isSending = false;
                    return;
                }

                isSending = true;
                byte[] data = sendCache.Dequeue();
                Send(new ArraySegment<byte>(data));
                isSending = false;
                Send();
            }
            catch (Exception e)
            {
                Console.WriteLine("Send():" + e.Message);
            }
        }

        /// <summary>
        /// 连接断开
        /// </summary>
        /// <param name="reason"></param>
        protected override void OnSessionClosed(CloseReason reason)
        {
            Console.WriteLine(uid + "PlayerSession  OnSessionClosed");
            isUse = false;
            base.OnSessionClosed(reason);
            Close();
            
        }

        /// <summary>
        /// 关闭
        /// </summary>
        public override void Close()
        {
            isUse = false;
            base.Close(); 
            if (ServNet.instance.Users.ContainsKey(uid))
            {
                ServNet.instance.Users.Remove(uid);
            }
            Console.WriteLine("Close uid "+uid);
        }
    }
}
